#include<cstdio>//uncle-lu
#include<cstring>
#include<stack>
#include<algorithm>
template<class T>void read(T &x)
{
	x=0;int f=0;char ch=getchar();
	while(ch<'0'||ch>'9') { f|=(ch=='-'); ch=getchar(); }
	while(ch<='9'&&ch>='0') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
	x = f ? -x : x;
	return ;
}	

const int N = 300010;
struct node{
	int v,next;
};
node edge[2*N];
int head[N], cnt;
int n, m;

void add_edge(int x, int y)
{
	edge[++cnt].v = y;
	edge[cnt].next= head[x];
	head[x] = cnt;
	return ;
}

int dfn[N], low[N], color[N], vis[N];
int tot, colornum;
std::stack<int>s;

int Tarjan(int now,int fa)
{
    dfn[now]=low[now]=++tot;
    vis[now]=1;
    s.push(now);
    for(int i=head[now];i!=-1;i=edge[i].next)
    {
        if(dfn[edge[i].v]==0)  
            Tarjan(edge[i].v,now),low[now]=std::min(low[now],low[edge[i].v]);
        else if(vis[edge[i].v]&&edge[i].v!=fa) 
            low[now]=std::min(low[now],dfn[edge[i].v]);
    }
    if(dfn[now]==low[now])
    {
        int top;
        ++colornum;
        do
        {
            top=s.top();    color[top]=colornum;
            vis[top]=0; s.pop();
        }while(top!=now);
    }

	return 0;
}

int main()
{
	freopen("in","r",stdin);
	memset(head, -1, sizeof(head));
	read(n);read(m);

	int x, y;
	for (int i = 1; i <= m; i++) 
	{
		read(x);read(y);
		add_edge(x, y);
		add_edge(y, x);
	}

	for (int i = 1; i <= n; i++) 
	{
		if(!dfn[i])
		{
			Tarjan(i, 0);
		}
	}

	for (int i = 1; i <= n; i++) 
	{
		printf("%d ", color[i]);
	}

	return 0;
}
